package link.jfire.socket.socketserver.transfer.handler.socket;

import java.nio.channels.CompletionHandler;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import link.jfire.baseutil.collection.ByteBufferPool;
import link.jfire.baseutil.simplelog.ConsoleLogFactory;
import link.jfire.baseutil.simplelog.Logger;
import link.jfire.socket.socketserver.bus.ServerChannelInfo;
import link.jfire.socket.socketserver.storage.WritePacket;

@Resource
public class MessageWriteHandler implements CompletionHandler<Integer, WritePacket>
{
    private final Logger logger = ConsoleLogFactory.getLogger();
    
    @Override
    public void completed(Integer result, WritePacket packet)
    {
        if (packet.getBuffer().hasRemaining())
        {
            if (logger.isTraceEnabled())
            {
                logger.trace("向通道{}数据写入不完整,写入{},当前状态{}", packet.getServerChannelInfo().getAddress(), result, packet.getBuffer());
            }
            packet.getServerChannelInfo().getSocketChannel().write(packet.getBuffer(), 10, TimeUnit.SECONDS, packet, this);
            return;
        }
        else
        {
            ByteBufferPool.returnBuffer(packet.getBuffer());
            logger.trace("向通道{}写入完毕,序号:{}", packet.getServerChannelInfo().getAddress(), packet.cursor());
            ServerChannelInfo channelInfo = packet.getServerChannelInfo();
            channelInfo.sendOne();
            packet = channelInfo.waitForSend();
            if (packet != null)
            {
                packet.tryWrite();
            }
            else
            {
                logger.trace("消息是空的，通道剩余是{}", channelInfo.left());
            }
        }
    }
    
    @Override
    public void failed(Throwable exc, WritePacket packet)
    {
        logger.error("向socket通道{}写入信息失败，关闭通道,buffer状态是{}", packet.getServerChannelInfo().getAddress(), packet.getBuffer(), exc);
        ByteBufferPool.returnBuffer(packet.getBuffer());
        packet.getServerChannelInfo().close();
    }
    
}
